package com.boge.parse.amf;

import java.io.ByteArrayOutputStream;

import com.boge.parse.base.BaseProtocolEncoder;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.AttributeKey;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

import com.boge.decoder.AES;
import com.boge.socket.ActionData;
import com.boge.util.ZlibUtil;

import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf3Output;

/**
 * 发送数据编码
 * @author boge
 *
 */
public class AmfProtocolEncoder extends BaseProtocolEncoder {

	private SerializationContext context = new SerializationContext();
	private final AttributeKey CONTEXT = new AttributeKey(getClass(), "context");  
	
	@Override
	public void encode(IoSession session, Object message,
			ProtocolEncoderOutput out) throws Exception {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		Amf3Output output = new Amf3Output(context);
		output.setOutputStream(outputStream);
		try {
			ActionData<?> ad = (ActionData<?>) message;
			output.writeLong(System.currentTimeMillis());// 发送当前服务器的时间
			output.writeInt(ad.getAction());
			output.writeObject(ad.getData());
			byte[] bytes = outputStream.toByteArray();
			// 加密
//			System.out.println(bytes.length);
			String str = getAes(session).encrypt(bytes);
			outputStream.reset();
			output.reset();
			bytes = str.getBytes();
			// 压缩
			bytes = ZlibUtil.compress(bytes);
			int len = bytes.length;
			output.writeInt(len);
			output.write(bytes, 0, bytes.length);
//			System.out.println(str);
//			System.out.println(bytes.length);
			// 之前未加密传送方式
//			output.writeInt(ad.getAction());
//			output.writeObject(ad.getData());
//			int len = outputStream.size();
//			outputStream.reset();
//			output.reset();
//			output.writeInt(len);
//			output.writeInt(ad.getAction());
//			output.writeObject(ad.getData());
//			System.out.println(len);
//			System.out.println(outputStream.size());
			out.write(IoBuffer.wrap(outputStream.toByteArray()));
		} finally {
			output.reset();
			output.close();
			outputStream.reset();
			outputStream.close();
		}
	}

	@Override
	public void dispose(IoSession session) throws Exception {
		AES aes = (AES) session.getAttribute(CONTEXT);  
		if (aes != null) {
			session.removeAttribute(CONTEXT);
		}
	}
	
	private AES getAes(IoSession session) {  
		AES aes;  
		aes = (AES) session.getAttribute(CONTEXT);  
        if (aes == null) {  
        	aes = new AES();  
            session.setAttribute(CONTEXT, aes);   
        }   
        return aes;  
    }

}
